package com.example.printerfile;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.printing.PDFPrintable;
import org.apache.pdfbox.printing.Scaling;

import javax.print.PrintService;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.standard.Sides;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件打印处理类
 */
public class Printer {
    /**
     * 文件打印处理类 不设置软队列 直接使用打印机队列
     * 仅仅处理PDF文件 后端会将文件统一转换为PDF文件
     * @param filePath
     * @return
     */
    public static boolean handlerFile(String filePath,String printerName)throws Exception{
        if(filePath == null){
            return false;
        }
        //处理文件
        File file = new File(filePath);
        PDDocument document = null;
        try{
           document = PDDocument.load(file);
            PrinterJob printerJob = PrinterJob.getPrinterJob();
            if(printerName != null){
                //获取打印机列表
                PrintService[] printServices = PrinterJob.lookupPrintServices();
                if(printServices == null || printServices.length<=0){
                    System.out.print("打印失败，未找到可用打印机，请检查。");
                    return false;
                }
                PrintService printService = null;
                //匹配指定打印机
                for (int i = 0;i < printServices.length; i++) {
                    if (printServices[i].getName().contains(printerName)) {
                        printService = printServices[i];
                        break;
                    }
                }
                if(printService!=null){
                    printerJob.setPrintService(printService);
                }else{
                    System.out.print("打印失败，未找到名称为" + printerName + "的打印机，请检查。");
                    return false;
                }

            }
            //设置纸张及缩放
            PDFPrintable pdfPrintable = new PDFPrintable(document, Scaling.ACTUAL_SIZE);
            //设置多页打印
            Book book = new Book();
            PageFormat pageFormat = new PageFormat();
            //设置打印方向
            pageFormat.setOrientation(PageFormat.PORTRAIT); //纵向
            pageFormat.setPaper(getPaper());
            book.append(pdfPrintable,pageFormat,document.getNumberOfPages());
            printerJob.setPageable(book);
            printerJob.setCopies(1);//设置打印份数
            //添加打印属性
            HashPrintRequestAttributeSet pars = new HashPrintRequestAttributeSet();
            pars.add(Sides.DUPLEX); //设置单双页
            printerJob.print(pars);

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (document != null) {
                try {
                    document.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return false;
    }

    public static Paper getPaper() {
        Paper paper = new Paper();
        // 默认为A4纸张，对应像素宽和高分别为 595, 842
        int width = 595;
        int height = 842;
        // 设置边距，单位是像素，10mm边距，对应 28px
        int marginLeft = 10;
        int marginRight = 0;
        int marginTop = 10;
        int marginBottom = 0;
        paper.setSize(width, height);
        // 下面一行代码，解决了打印内容为空的问题
        paper.setImageableArea(marginLeft, marginRight, width - (marginLeft + marginRight), height - (marginTop + marginBottom));
        return paper;
    }

    /**
     * 获取打印机列表
     * @return
     */
    public static List<String> getPrinterList(){
        ArrayList<String> list = new ArrayList<>();
        try{
            //获取打印机列表
            PrintService[] printServices = PrinterJob.lookupPrintServices();
            if(printServices == null || printServices.length<=0){
                System.out.print("打印失败，未找到可用打印机，请检查。");
            }
            //匹配指定打印机
            for (int i = 0;i < printServices.length; i++) {
                list.add(printServices[i].getName());
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return list;
    }
}
